package com.ruoyi.yipaiju.controller;

import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.ApiResult;
import com.ruoyi.common.core.domain.entity.XcxRole;
import com.ruoyi.common.core.domain.entity.XcxUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataApi;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.yipaiju.domain.*;
import com.ruoyi.yipaiju.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/users")
public class UsersController extends BaseController {

    @Autowired
    private IXcxUserService xcxUserService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private IWechatService wechatService;
    @Autowired
    private IAccessLogService accessLogService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private IRolesService rolesService;
    @Autowired
    private IUserInvitesService userInvitesService;
    @Autowired
    private RedisCache redisCache;

    /**
     * 小程序用户列表
     * @param xcxUser
     * @return
     */
    @GetMapping("")
    public TableDataApi list(XcxUser xcxUser)
    {
        startPageApi();
        List<XcxUser> list = xcxUserService.selectXcxUserList(xcxUser);
        return getTableApi(list);
    }

    /**
     * 我的信息
     * @return
     */
    @GetMapping("/me")
    public ApiResult me()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 不知道这个角色咋给的。。。
//        loginUser.getXcxUser().setActive_role_id(1L);
//        loginUser.getXcxUser().setRole_code("renter_ceo");
//        loginUser.getXcxUser().setGroup_id(1L);
//        loginUser.getXcxUser().setOrganization_id(2L);
        return ApiResult.success(loginUser.getXcxUser());
    }

    /**
     * 获取用户手机号
     * @return
     */
    @GetMapping("/{userId}/phone")
    public ApiResult phone(@PathVariable("userId") Long userId)
    {
        XcxUser xcxUser = xcxUserService.selectXcxUserById(userId);
        return ApiResult.success(xcxUser);
    }

    /**
     * 获取用户访问记录
     * @return
     */
    @GetMapping("/{userId}/access-log")
    public ApiResult accessLog(@PathVariable("userId") Long userId)
    {
        startPageApi();
        List<AccessLog> accessLogs = accessLogService.selectAccessLogList(Builder.of(AccessLog::new).with(AccessLog::setUserId, userId).build());
        return ApiResult.success(ImmutableMap.of("results", accessLogs));
    }

    /**
     * 更新我的信息
     * @param xcxUser
     * @return
     */
    @PostMapping("/me/info")
    public ApiResult meInfo(@RequestBody XcxUser xcxUser)
    {

        LoginUser loginUser = SecurityUtils.getLoginUser();
        XcxUser dbUser = loginUser.getXcxUser();
        // 无条件修改 用户自定义修改
        if ("1".equals(xcxUser.getExt1())){
            dbUser.setAvatarUrl(xcxUser.getAvatarUrl());
            dbUser.setNickname(xcxUser.getNickname());
            dbUser.setGender(xcxUser.getGender());
            dbUser.setPhone(xcxUser.getPhone());
            dbUser.setExt1(xcxUser.getExt1());
            xcxUserService.updateXcxUser(dbUser);
            tokenService.refreshToken(loginUser);
        }else {
            // 判断用户如果是空的则修改
            if (StringUtils.isEmpty(dbUser.getNickname())){
                dbUser.setAvatarUrl(xcxUser.getAvatarUrl());
                dbUser.setNickname(xcxUser.getNickname() + dbUser.getId());
                dbUser.setGender(xcxUser.getGender());
                dbUser.setLoginTime(new Date());
                xcxUserService.updateXcxUser(dbUser);
                tokenService.refreshToken(loginUser);
            }
        }

        return ApiResult.success(dbUser);
    }

    /**
     * 获取微信手机号
     * @param wechatLogin
     * @return
     */
    @PostMapping("/me/phone/wechat")
    public ApiResult mePhoneWechat(@RequestBody WechatLogin wechatLogin)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        JSONObject jsonObject = wechatService.getUserInfo(wechatLogin.getEncryptedData(), loginUser.getXcxUser().getSessionKey(), wechatLogin.getIv());
        loginUser.getXcxUser().setPhone(jsonObject.getString("phoneNumber"));
        loginUser.getXcxUser().setPhone_is_verified(true);
        xcxUserService.updateXcxUser(loginUser.getXcxUser());
        tokenService.refreshToken(loginUser);
        return ApiResult.success(loginUser.getXcxUser());
    }

    /**
     * 修改自己的手机号
     * @param smsModel
     * @return
     */
    @PostMapping("/code/vali")
    public ApiResult mePhone(@RequestBody SmsModel smsModel)
    {
        // 去redis验证
        String code = redisCache.getCacheObject("code:"+smsModel.getUuid());
        if ("000000".equals(smsModel.getCode()) || (StringUtils.isNotEmpty(smsModel.getCode()) && smsModel.getCode().equals(code))){
            // TODO 只验证不做操作
//            // 验证成功修改
//            LoginUser loginUser = SecurityUtils.getLoginUser();
//            loginUser.getXcxUser().setPhone(smsModel.getPhone());
//            xcxUserService.updateXcxUser(loginUser.getXcxUser());
//            tokenService.refreshToken(loginUser);
            return ApiResult.success();
        }else {
            return ApiResult.error("验证码错误");
        }
    }

    /**
     * 登出
     * @return
     */
    @GetMapping("/logout")
    public ApiResult logout()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        tokenService.delLoginUser(loginUser.getToken());
        return ApiResult.success();
    }

    /**
     * 授权  TODO 这里有个问题就是用户怎么更新授权的数据 ，  现在只有重新登录才是生效的
     * @param xcxUser
     * @return
     */
    @PostMapping("/roles/promote")
    public ApiResult rolePromote(@RequestBody XcxUser xcxUser)
    {
        XcxUser xcxUser1 = xcxUserService.selectXcxUserById(xcxUser.getId());
        if (xcxUser1 != null){
            // 删除原角色插入新的
            userRoleService.deleteUserRoleByCondition(Builder.of(UserRole::new).with(UserRole::setUserId, xcxUser.getId()).build());
            if (xcxUser.getRoleIds() != null && xcxUser.getRoleIds().size() > 0){
                for (Long roleId : xcxUser.getRoleIds()) {
                    userRoleService.insertUserRole(Builder.of(UserRole::new).with(UserRole::setUserId, xcxUser.getId()).with(UserRole::setRoleId, roleId).build());
                }
                //  只要重新授权就把激活角色改为第一个 ，因为怕授权里没有现在激活的
                xcxUser1.setActive_role_id(xcxUser.getRoleIds().get(0));
            }else {
                xcxUser1.setActive_role_id(null);
            }
            // 刷新用户的token
            xcxUser1 = xcxUserService.getXcxUserLogin(xcxUser1);
            LoginUser loginUser = new LoginUser(xcxUser1.getId(), null, xcxUser1, null);
            String token = Constants.JWT_USERID + "_" + loginUser.getUserId();
            loginUser.setToken(token);
            tokenService.refreshToken(loginUser);
            return ApiResult.success();
        }
        return ApiResult.error();
    }

    /**
     * 用户认证
     * @param userId
     * @return
     */
    @PostMapping("/{userId}/set-verified")
    public ApiResult setVerified(@PathVariable("userId") Long userId)
    {
        XcxUser xcxUser = xcxUserService.selectXcxUserById(userId);
        if (xcxUser != null){
            xcxUser.setIs_verified(1L);
            xcxUserService.updateXcxUser(xcxUser);
            return ApiResult.success();
        }
        return ApiResult.error();
    }

    /**
     * 用户的权限
     * @param userId
     * @return
     */
    @GetMapping("/{userId}/roles")
    public ApiResult roles(@PathVariable("userId") Long userId)
    {
        List<XcxRole> xcxRoles = xcxUserService.selectXcxRoleByUserId(userId);
        return ApiResult.success(ImmutableMap.of("granted_role_set", xcxRoles));
    }

    /**
     * 切换激活的权限
     * @param roleId
     * @return
     */
    @PostMapping("/me/roles/{roleId}/active")
    public ApiResult rolesActive(@PathVariable("roleId") Long roleId)
    {
        Roles roles = rolesService.selectRolesById(roleId);
        if (roles != null){
            XcxRole xcxRole = new XcxRole();
            BeanUtils.copyProperties(roles, xcxRole);
            LoginUser loginUser = SecurityUtils.getLoginUser();
            XcxUser xcxUser = loginUser.getXcxUser();
            xcxUser.setActive_role_id(roleId);
            xcxUser.setActive_role(xcxRole);
            xcxUser.setRole_code(roles.getCode());
            xcxUserService.updateXcxUser(xcxUser);
            tokenService.refreshToken(loginUser);
            return ApiResult.success();
        }
        return ApiResult.error();
    }

    /**
     * 建立邀请关系
     * @param invitesId
     * @return
     */
    @PostMapping("/{invitesId}/invites")
    public ApiResult invites(@PathVariable("invitesId") Long invitesId)
    {
        Long userId = SecurityUtils.getUserId();
        if (invitesId.longValue() != userId.longValue()){
            UserInvites build = Builder.of(UserInvites::new)
                    .with(UserInvites::setInvitesId, invitesId)
                    .with(UserInvites::setUserId, SecurityUtils.getUserId())
                    .build();
            UserInvites userInvites = userInvitesService.selectOneUserInvites(build);
            if (userInvites == null){
                build.setDepth(1);
                userInvitesService.insertUserInvites(build);
            }
        }
        return ApiResult.success();
    }

    /**
     * 获取邀请列表
     * @param userId
     * @param depth 1：一级邀请，2：二级邀请
     * @return
     */
    @GetMapping("/{userId}/invites")
    public TableDataApi invitesList(@PathVariable("userId") Long userId, Integer depth)
    {
        List<UserInvites> userInvites = new ArrayList<>();
        if (depth == 1){
            startPageApi();
            userInvites = userInvitesService.selectUserInvitesList2(Builder.of(UserInvites::new)
                    .with(UserInvites::setInvitesId, userId)
                    .build());
        }else if (depth == 2){
            // 获取我邀请的一级  然后再查询二级
            List<UserInvites> userInvites1 = userInvitesService.selectUserInvitesList(Builder.of(UserInvites::new)
                    .with(UserInvites::setInvitesId, userId)
                    .build());
            if (userInvites1 != null && userInvites1.size() > 0){
                startPageApi();
                userInvites = userInvitesService.selectUserInvitesList2(Builder.of(UserInvites::new)
                        .with(UserInvites::setInviUser, "true")
                        .with(UserInvites::setInvitesIds, userInvites1.stream().map(item -> item.getUserId()).collect(Collectors.toList()))
                        .build());
            }
        }
        return getTableApi(userInvites);
    }


    /**
     * 用户邀请关系，返回一级邀请人和二级邀请人
     * @param userId
     * @return
     */
    @PostMapping("/invites/relation/{userId}")
    public ApiResult invitesRelation(@PathVariable("userId") Long userId){
        UserInvites userInvitesFirst = userInvitesService.selectOneUserInvites(Builder.of(UserInvites::new)
                .with(UserInvites::setUserId, userId)
                .build());
        UserInvites userInvitesSecond = null;
        if (userInvitesFirst != null){
            XcxUser xcxUser1 = xcxUserService.selectXcxUserById(userInvitesFirst.getInvitesId());
            if (xcxUser1 != null){
                userInvitesFirst.setNickname(xcxUser1.getNickname());
                userInvitesFirst.setAvatarUrl(xcxUser1.getAvatarUrl());
                userInvitesFirst.setPhone(xcxUser1.getPhone());
            }
            // 获取二级邀请
            userInvitesSecond = userInvitesService.selectOneUserInvites(Builder.of(UserInvites::new)
                    .with(UserInvites::setUserId, userInvitesFirst.getInvitesId())
                    .build());
            if (userInvitesSecond != null){
                XcxUser xcxUser2 = xcxUserService.selectXcxUserById(userInvitesSecond.getInvitesId());
                if (xcxUser2 != null){
                    userInvitesSecond.setNickname(xcxUser2.getNickname());
                    userInvitesSecond.setAvatarUrl(xcxUser2.getAvatarUrl());
                    userInvitesSecond.setPhone(xcxUser2.getPhone());
                }
            }
        }
        return ApiResult.success(ImmutableMap.of(
                "first", userInvitesFirst == null ? "" : userInvitesFirst,
                "second", userInvitesSecond == null ? "" : userInvitesSecond));
    }


}
